package robot;

import java.awt.Dimension;
import java.awt.Graphics2D;

import robot.map.ObjectType;


public class Robot {
	
	private MainWindow mainWindow;
	private Dimension position;
	private int direction;

	public Robot(Dimension position, MainWindow mainWindow) {
		super();
		this.position = position;
		this.mainWindow = mainWindow;
		direction = 90;
	}

	public void paintRobot(Graphics2D g) {
		
		// case
		g.setColor(Const.ROBOT_CASE);
		g.fillOval(position.width, position.height,
				Const.DIAMETER, Const.DIAMETER);
		
		// front
		g.setColor(Const.ROBOT_FRONT);
		g.drawArc(position.width, position.height,
				Const.DIAMETER, Const.DIAMETER, direction - 90, 180);
		g.drawArc(position.width+1, position.height+1,
				Const.DIAMETER-2, Const.DIAMETER-2, direction - 90, 180);
	}
	
	public boolean stepForward() {
		
		Dimension tmpPosition = new Dimension(position);
		makeStep(tmpPosition);
		
		Dimension center = new Dimension(
				tmpPosition.width + (Const.DIAMETER/2),
				tmpPosition.height + (Const.DIAMETER/2));
		
		// check if can go
		byte[][] map = mainWindow.getEnvironmentMap().getMap();
		for (int i=tmpPosition.width ; i<Const.DIAMETER + tmpPosition.width ; i++) {
			for (int j=tmpPosition.height ; j<Const.DIAMETER + tmpPosition.height ; j++) {
				if (i < 1000 && j < 1000 && i >= 0 && j >= 0) {
					if (pointIsInCircle(center, i, j) && map[i][j] == 1) {
						return false;
					}
				}
				else {
					return false;
				}
			}
		}
		
		// mark clean place
		for (int i=tmpPosition.width ; i<Const.DIAMETER + tmpPosition.width ; i++) {
			for (int j=tmpPosition.height ; j<Const.DIAMETER + tmpPosition.height ; j++) {
				if (pointIsInCircle(center, i, j)) {
					mainWindow.getMemoryMap().addPoint(ObjectType.CLEAN, i, j);
				}
			}
		}
		
		makeStep(position);
		
		return true;
	}
	
	private void makeStep(Dimension dim) {
		switch (direction) {
		case 0:
			dim.width++;
			break;
			
		case 45:
			dim.height--;
			dim.width++;
			break;
			
		case 90:
			dim.height--;
			break;
			
		case 135:
			dim.width--;
			dim.height--;
			break;
			
		case 180:
			dim.width--;
			break;
			
		case 225:
			dim.width--;
			dim.height++;
			break;
			
		case 270:
			dim.height++;
			break;
			
		case 315:
			dim.width++;
			dim.height++;
			break;

		default:
			break;
		}
	}
	
	public void turnLeft() {
		addAngle(45);
		mainWindow.getConsolePanel().addText("Bieżący kierunek ruchu: "
		+ Integer.toString(direction));
	}
	
	public void turnRight() {
		addAngle(315);
		mainWindow.getConsolePanel().addText("Bieżący kierunek ruchu: "
		+ Integer.toString(direction));
	}
	
	private void addAngle(int angle) {
		direction = (direction + angle) % 360;
	}
	
	private boolean pointIsInCircle(Dimension center, int x, int y) {
		x = center.width - x;
		x = x*x;
		y = center.height - y;
		y = y*y;
		int l = Const.DIAMETER/2 - 1;
		l = l*l;
		if (x+y<=l) {
			return true;
		}
		else {
			return false;
		}
	}
	
	public void rotate(Dimension dimension) {
		int x = dimension.width;
		int y = dimension.height;
		int rx = position.width + 15;
		int ry = position.height + 15;
		
		if (rx == x) {
			if (ry > y) {
				direction = 90;
			}
			else {
				direction = 270;
			}
		}
		
		if (ry == y) {
			if (rx > x) {
				direction = 180;
			}
			else {
				direction = 0;
			}
		}
		
		if (rx > x) {
			if (ry > y) {
				direction = 135;
			}
			else {
				direction = 225;
			}
		}
		
		if (rx < x) {
			if (ry > y) {
				direction = 45;
			}
			else {
				direction = 315;
			}
		}
	}
	
	public Dimension getPosition() {
		return new Dimension(position.width+15, position.height+15);
	}

}
